package com.tiancheng.trade.payment.channel.ums;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.tiancheng.trade.commom.core.data.Result;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.commom.web.http.PlatformRequest;
import com.tiancheng.trade.payment.channel.ums.params.UmsCloseOrderResult;
import com.tiancheng.trade.payment.channel.ums.params.UmsQrcUnifiedParams;
import com.tiancheng.trade.payment.channel.ums.utils.UmsConstant;
import com.tiancheng.trade.payment.channel.ums.utils.UmsQrcUtil;
import com.tiancheng.trade.payment.enums.UmsReqTypeEnum;
import com.tiancheng.trade.payment.model.QrFlow;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.http.client.methods.HttpPost;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: likailun
 * @Description: 银联二维码支付组建
 * @Date: create in 2021/8/28 2:57 下午
 */
@Component
@Slf4j
public class UmsQrcPayComponent {
    @Resource
    private UmsConfig umsConfig;
    @Resource
    private PlatformRequest platformRequest;

    public Result<UmsQrcUnifiedParams> unifiedOrder(UmsQrcUnifiedParams params){
        final UmsProperties umsProperties = umsConfig.getByOrgPayChannelId(params.getOrgPaymentChannelId());
        params.setVersion(umsProperties.getQrcProperties().getVersion());
        params.setReqType("0210000903");
        params.setIssCode(umsProperties.getQrcProperties().getIssCode());
        params.setEncryptCertId(UmsQrcUtil.getEncryptCertId());

        Map<String, String> requestParam = JSON.parseObject(JSON.toJSONString(params, SerializerFeature.WriteMapNullValue), Map.class);
        final Map<String, String> afterSignParam = UmsQrcUtil.sign(requestParam, umsProperties);
        BusinessErrorInfoEnum.CHANNEL_PAY_FAIL_SIGN_ERROR.assertIsTrue(afterSignParam.containsKey(UmsConstant.PARAM_SIGNATURE));
        log.info("获取二维码订单，params：{}", JSON.toJSONString(afterSignParam));

        final String response = platformRequest.extendRequest(umsProperties.getQrcProperties().getQrcB2cIssBackTransUrl(), HttpPost.METHOD_NAME, null, afterSignParam, false, null);
        final UmsCloseOrderResult closeOrderResult = JsonUtil.fromJson(response, UmsCloseOrderResult.class);

        Map<String, String> rspData = null;
        final Result<UmsQrcUnifiedParams> result = new Result<>();
        result.setRet(0);
        try {
            rspData = UmsQrcUtil.convertResultStringToMap(response);
            if(!rspData.isEmpty()){
                log.info("获取二维码订单,银联返回：{}",JSON.toJSONString(rspData));
                if(UmsQrcUtil.validate(rspData, UmsConstant.ENCODING)){
                    log.info("获取二维码订单-验证签名成功");
                    if(MapUtils.getString(rspData,"respCode").equals("00")){
                        result.setData(JSON.parseObject(JSON.toJSONString(rspData, SerializerFeature.WriteMapNullValue), UmsQrcUnifiedParams.class));
                    }else{
                        result.setRet(1);
                        result.setMsg(MapUtils.getString(rspData,"respMsg"));
                    }
                    return result;
                }else{
                    log.error("获取二维码订单-验证签名失败");
                    result.setRet(1);
                    result.setMsg("验证签名失败");
                    return result;
                }
            }else{
                //未返回正确的http状态
                log.error("获取二维码订单-未获取到返回报文或返回http状态码非200");
                result.setRet(1);
                result.setMsg("未获取到返回报文或返回http状态码非200");
                return result;
            }
        } catch (Exception e) {
            log.error("获取二维码订单-获取二维码失败:",e);
            result.setRet(1);
            result.setMsg("获取二维码失败,未知异常");
            return result;
        }
    }

    public Result<UmsQrcUnifiedParams> queryQrInfo(UmsQrcUnifiedParams params){
        final UmsProperties umsProperties = umsConfig.getByOrgPayChannelId(params.getOrgPaymentChannelId());
        params.setVersion(umsProperties.getQrcProperties().getVersion());
        params.setReqType("0210000903");
        params.setIssCode(umsProperties.getQrcProperties().getIssCode());
        Map<String, String> requestParam = JSON.parseObject(JSON.toJSONString(params, SerializerFeature.WriteMapNullValue), Map.class);
        final Map<String, String> afterSignParam = UmsQrcUtil.sign(requestParam, umsProperties);
        BusinessErrorInfoEnum.CHANNEL_PAY_FAIL_SIGN_ERROR.assertIsTrue(afterSignParam.containsKey(UmsConstant.PARAM_SIGNATURE));
        log.info("查询二维码支付结果，params：{}", JSON.toJSONString(afterSignParam));

        final String response = platformRequest.extendRequest(umsProperties.getQrcProperties().getQrcB2cIssBackTransUrl(), HttpPost.METHOD_NAME, null, params, false, null);
        Map<String, String> rspData = null;
        final Result<UmsQrcUnifiedParams> result = new Result<>();
        result.setRet(0);
        try {
            rspData = UmsQrcUtil.convertResultStringToMap(response);
            if(!rspData.isEmpty()){
                log.info("查询二维码订单,银联返回：{}",JSON.toJSONString(rspData));
                if(UmsQrcUtil.validate(rspData, UmsConstant.ENCODING)){
                    if(MapUtils.getString(rspData,"respCode").equals("00")){
                        log.info("查询二维码订单-验证签名成功");
                        result.setData(JSON.parseObject(JSON.toJSONString(rspData, SerializerFeature.WriteMapNullValue), UmsQrcUnifiedParams.class));
                    }else{
                        result.setRet(1);
                        result.setMsg(MapUtils.getString(rspData,"respMsg"));
                    }
                    // 查询结果
                    return result;
                }else{
                    log.error("查询二维码订单-验证签名失败");
                    result.setRet(1);
                    result.setMsg("验证签名失败");
                    return result;
                }
            }else{
                //未返回正确的http状态
                log.error("查询二维码订单-未获取到返回报文或返回http状态码非200");
                result.setRet(1);
                result.setMsg("未获取到返回报文或返回http状态码非200");
                return result;
            }
        } catch (Exception e) {
            log.error("查询二维码订单-失败:",e);
            result.setRet(1);
            result.setMsg("获取二维码失败,未知异常");
            return result;
        }
    }

    /**
     * 银联附加处理通知
     * @param qrFlow 交易中台二维码支付流水
     * @param addnRecevie 银联附加处理请求参数
     * @param respCode 返回银联的响应吗
     * @return
     */
    public Result sendC2BAddnRecevieNotify(QrFlow qrFlow, @NotNull Map<String, String> addnRecevie,@NotEmpty String respCode){
        final UmsProperties umsProperties = umsConfig.getByOrgPayChannelId(qrFlow.getOrgPaymentChannelId());
        Map<String,String> contentData = new HashMap<String,String>();
        contentData.put("version", umsProperties.getQrcProperties().getVersion());
        contentData.put("reqType", UmsReqTypeEnum.C2B_ADDN_RECEIVE_NOTIFY.getCode());
        contentData.put("issCode", umsProperties.getQrcProperties().getIssCode());

        contentData.put("qrNo", qrFlow.getQrNo());
        contentData.put("respCode", respCode);//可以按照规范修改应答码
        contentData.put("respMsg", respCode.equals("00")?"成功":"失败");
        if(addnRecevie.containsKey("upReserved")){
            contentData.put("upReserved", MapUtils.getString(addnRecevie,"addnRecevie"));
        }

        contentData.put("voucherNum", MapUtils.getString(addnRecevie,"voucherNum"));
        //contentData.put("encryptCertId", UmsQrcUtil.getEncryptCertId());

        Map<String, String> afterSignParam = UmsQrcUtil.sign(contentData, umsProperties);
        BusinessErrorInfoEnum.CHANNEL_PAY_FAIL_SIGN_ERROR.assertIsTrue(afterSignParam.containsKey(UmsConstant.PARAM_SIGNATURE));
        log.info("附加处理通知发送-发送银联附加处理通知：{}",JSON.toJSONString(afterSignParam));
        final String response = platformRequest.extendRequest(umsProperties.getQrcProperties().getQrcB2cIssBackTransUrl(), HttpPost.METHOD_NAME, null, afterSignParam, false, null);

        Map<String, String> rspData = null;
        final Result<UmsQrcUnifiedParams> result = new Result<>();
        result.setRet(0);
        try {
            rspData = UmsQrcUtil.convertResultStringToMap(response);
            if(!rspData.isEmpty()){
                log.info("附加处理通知发送-银联附加处理通知,银联返回：{}",JSON.toJSONString(rspData));
                if(UmsQrcUtil.validate(rspData, UmsConstant.ENCODING)){
                    if(MapUtils.getString(rspData,"respCode").equals("00")){
                        log.info("附加处理通知发送-验证签名成功");
                        result.setData(JSON.parseObject(JSON.toJSONString(rspData, SerializerFeature.WriteMapNullValue), UmsQrcUnifiedParams.class));
                    }else{
                        result.setRet(1);
                        result.setMsg(MapUtils.getString(rspData,"respMsg"));
                    }

                    return result;
                }else{
                    log.error("附加处理-验证签名失败");
                    result.setRet(1);
                    result.setMsg("验证签名失败");
                    return result;
                }
            }else{
                //未返回正确的http状态
                log.error("附加处理通知发送-未获取到返回报文或返回http状态码非200");
                result.setRet(1);
                result.setMsg("未获取到返回报文或返回http状态码非200");
                return result;
            }
        } catch (Exception e) {
            log.error("附加处理通知发送-失败:",e);
            result.setRet(1);
            result.setMsg("获取二维码失败,未知异常");
            return result;
        }
    }
}
